package org.ewancle.springbootelasticsearch.service.impl;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.IndexRequest;
import co.elastic.clients.elasticsearch.core.IndexResponse;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.ewancle.springbootelasticsearch.model.Document;
import org.ewancle.springbootelasticsearch.service.ElasticsearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

// https://juejin.cn/post/7080726607043756045
// https://my.oschina.net/lenve/blog/5610310
@Service
public class ElasticsearchServiceImpl implements ElasticsearchService {

    @Value("${elasticsearch.index}")
    private String index;


    @Autowired
    private ElasticsearchClient elasticsearchClient;

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public String indexDocument(Document document) throws IOException {
        // 使用8.x的API创建索引
        String documentJson = objectMapper.writeValueAsString(document);
        IndexRequest<Object> indexRequest = new IndexRequest.Builder<>()
                .index("products")
                .id("sd")
                .document(document)
                .build();
        IndexResponse indexResponse = elasticsearchClient.index(indexRequest);

        /*elasticsearchClient.indices().create(c ->
                c.index("documentJson")
                        .settings(s -> s.numberOfShards("6").numberOfReplicas("1").codec("zstd"))

                ;
        );*/
        return indexResponse.id();
    }

    @Override
    public Document getDocumentById(String id) throws IOException {
        return null;
    }

    @Override
    public boolean deleteDocument(String id) throws IOException {
        return false;
    }



   /* @Override
    public boolean deleteDocument(String id) throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest(index, id);
        DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        return deleteResponse.status().getStatus() == 200;
    }*/

    @Override
    public List<Document> searchDocuments(String field, String query) throws IOException {
        // 使用ES 8.x API执行搜索
        List<Document> results = new ArrayList<>();

        SearchResponse<Document> response =
                elasticsearchClient.search(s -> s
                                .index(index)
                                .query(q -> q
                                        .match(m -> m
                                                .field(field)
                                                .query(query)
                                        )
                                ),
                        Document.class
                );

        for (Hit<Document> hit : response.hits().hits()) {
            results.add(hit.source());
        }

        return results;
    }

    @Override
    public List<Document> advancedSearch(Map<String, Object> searchCriteria, int from, int size) throws IOException {
        return List.of();
    }

    @Override
    public void bulkIndex(List<Document> documents) throws IOException {

    }

    /*@Override
    public List<Document> advancedSearch(Map<String, Object> searchCriteria, int from, int size) throws IOException {
        // 使用7.x的API执行高级搜索
        List<Document> results = new ArrayList<>();
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // 构建查询条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        for (Map.Entry<String, Object> entry : searchCriteria.entrySet()) {
            String field = entry.getKey();
            Object value = entry.getValue();

            if (value instanceof String) {
                boolQueryBuilder.must(QueryBuilders.matchQuery(field, value));
            } else if (value instanceof Number) {
                boolQueryBuilder.must(QueryBuilders.termQuery(field, value));
            } else if (value instanceof Map) {
                // 处理范围查询，如 {"price": {"gte": 100, "lte": 200}}
                Map<String, Object> rangeParams = (Map<String, Object>) value;
                boolQueryBuilder.must(QueryBuilders.rangeQuery(field)
                        .from(rangeParams.get("gte"))
                        .to(rangeParams.get("lte"))
                        .includeLower(true)
                        .includeUpper(true));
            }
        }

        searchSourceBuilder.query(boolQueryBuilder);
        searchSourceBuilder.from(from);
        searchSourceBuilder.size(size);
        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        for (SearchHit hit : searchResponse.getHits().getHits()) {
            String sourceAsString = hit.getSourceAsString();
            Document document = objectMapper.readValue(sourceAsString, Document.class);
            results.add(document);
        }

        return results;
    }

    @Override
    public void bulkIndex(List<Document> documents) throws IOException {
        BulkRequest bulkRequest = new BulkRequest();

        for (Document document : documents) {
            String documentJson = objectMapper.writeValueAsString(document);
            IndexRequest indexRequest = new IndexRequest(index)
                    .id(document.getId())
                    .source(documentJson, XContentType.JSON);
            bulkRequest.add(indexRequest);
        }

        BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        if (bulkResponse.hasFailures()) {
            throw new IOException("Bulk indexing failed: " + bulkResponse.buildFailureMessage());
        }
    }*/
}

